Volatility surface 2¶

In [1]:
import yfinance as yf
import numpy as np
import pandas as pd
import plotly.graph_objects as go
In [2]:
symbol = "^SPX"
ticker = yf.Ticker(symbol)

expirations = [ticker.options[1],ticker.options[4],ticker.options[6],ticker.options[9],
               ticker.options[11],ticker.options[14], ticker.options[24],
              ticker.options[28], ticker.options[32], ticker.options[34], ticker.options[35], ticker.options[38],
              ticker.options[41],  ticker.options[36]]
call_data = []

for exp_date in expirations:
    option_chain = ticker.option_chain(exp_date)
    calls = option_chain.calls
    calls['ExpirationDate'] = exp_date
    calls = calls[calls["impliedVolatility"] > 0.01]
    call_data.append(calls)
In [3]:
import plotly.graph_objs as go

fig = go.Figure()
filtered_datasets = [calls for calls in call_data if not calls.empty]

line_size = 3
surface_colorscale = 'plasma'


for dataset in filtered_datasets:
    trace = go.Scatter3d(
        x=dataset["strike"],
        y=dataset["ExpirationDate"],
        z=dataset["impliedVolatility"],
        mode="lines",
        line=dict(color='black', width=line_size)
    )
    fig.add_trace(trace)

x_mesh = []
y_mesh = []
z_mesh = []

for dataset in filtered_datasets:
    x_mesh.extend(dataset["strike"])
    y_mesh.extend(dataset["ExpirationDate"])
    z_mesh.extend(dataset["impliedVolatility"])


color_array = z_mesh 

mesh = go.Mesh3d(
    x=x_mesh,
    y=y_mesh,
    z=z_mesh,
    opacity= 0.7,
    intensity=color_array,  
    colorscale=surface_colorscale,  
    colorbar=dict(title="Implied Volatility"),  
    showscale=False  
)

fig.add_trace(mesh)

# layout
layout = go.Layout(
    scene=dict(
        xaxis_title='Strike',  
        yaxis_title="Expiration Date",
        zaxis_title="Implied Volatility",
    ),
    margin=dict(l=0, r=0, b=0, t=0),
)

fig.update_layout(
    width=1000,
    height=1000,
    autosize=False,
    scene=dict(
        camera=dict(
            up=dict(
                x=0,
                y=0,
                z=1
            ),
            eye=dict(
                x=0,
                y=1,
                z=1,
            )
        ),
        aspectratio=dict(x=1, y=1, z=1),
        aspectmode='manual'
    ),
)


fig.show()
In [4]:
import plotly.graph_objs as go

fig = go.Figure()
filtered_datasets = [calls for calls in call_data if not calls.empty]

line_size = 3
surface_colorscale = 'plasma'


for dataset in filtered_datasets:
    trace = go.Scatter3d(
        x=dataset["strike"],
        y=dataset["ExpirationDate"],
        z=dataset["impliedVolatility"],
        mode="lines",
        line=dict(color='black', width=line_size)
    )
    fig.add_trace(trace)

x_mesh = []
y_mesh = []
z_mesh = []

for dataset in filtered_datasets:
    x_mesh.extend(dataset["strike"])
    y_mesh.extend(dataset["ExpirationDate"])
    z_mesh.extend(dataset["impliedVolatility"])


color_array = z_mesh  

mesh = go.Mesh3d(
    x=x_mesh,
    y=y_mesh,
    z=z_mesh,
    opacity= 1,
    intensity=color_array,  
    colorscale=surface_colorscale,  
    colorbar=dict(title="Implied Volatility"),  
    showscale=False  
)

fig.add_trace(mesh)

# layout
layout = go.Layout(
    scene=dict(
        xaxis_title='Strike',  # Set the x-axis title here
        yaxis_title="Expiration Date",
        zaxis_title="Implied Volatility",
    ),
    margin=dict(l=0, r=0, b=0, t=0),
)

fig.update_layout(
    width=1000,
    height=1000,
    autosize=False,
    scene=dict(
        camera=dict(
            up=dict(
                x=0,
                y=0,
                z=1
            ),
            eye=dict(
                x=0,
                y=1,
                z=1,
            )
        ),
        aspectratio=dict(x=1, y=1, z=1),
        aspectmode='manual'
    ),
)

fig.show()